/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Copyright(C) Harry Wei (harryxiyou@gmail.com), 2011
 */

/*
 * The project aim at compress files and decompress
 * them from our compressed files.
 * See README for details.
 */

#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>

#include "./include/cda.h"

int 
main(int argc, char *argv[])
{
	int i;
	int counter;
	int db_counter;
	struct huffcode *hc = NULL;
	struct ch_fre *effect_fre = NULL;
	char ch_num = CHAR_STA;
	struct ch_fre get_ch_fre[CHAR_NUM];
	struct huffman *get_huff = NULL;

	switch (argc) {
	case 0:
		fprintf(stderr, "please enter orignal file & compressed file & decompressed file\n");
		break;
	case 1:
		fprintf(stderr, "please enter decompressed file\n");
		break;
	case 2:
		if (dcompress_file(argv[1]))
			return 1; 
		break;
	case 3:
		CAL_AMOUNT(counter, ch_num, get_ch_fre);	/* init all the chars */
		if (cal_ch_fre(argv[1], get_ch_fre))		/* calculate the characters' amounts */	
			return 1;
		counter = 0;
		CAL_NUM(counter, get_ch_fre, effect_fre);	/* calculate the efficient chars */

#if defined(DEBUG) && DEBUG == 1
		printf("NUM:  %d\n", counter);
		for (i = 1; i < counter + 1; i++) {
			printf("efficient: %d %d\n", 
				effect_fre[i].fre, effect_fre[i].ch);
		}
#endif
		hc = (struct huffcode *)malloc(
			sizeof(struct huffcode) * (counter + 1));
		if (!hc) {
			fprintf(stderr, "Allocate Error!\n");
			return 1;
		}
		get_huff = (struct huffman *)malloc(
			sizeof(struct huffman) * (counter + 1));
		if (!get_huff) {
			fprintf(stderr, "Allocate Error!\n");
			return 1;
		}
		if (creat_huffman(get_huff, effect_fre, counter))
			return 1;
		if (creat_huffmancode(get_huff, hc, effect_fre, counter))
			return 1;
		if (compress_file(argv[1], argv[2], effect_fre, hc, counter))
			return 1;

#if DEBUG == 2 		/*#if defined(DEBUG) && defined(DEBUG)*/
		for (i = 1; i < counter + 1; i++) {
			printf("%d: ", hc[i].ch);
			for (db_counter = hc[i].begin; 
					db_counter < CHAR_USE; db_counter++) {
				printf("%d", hc[i].code[db_counter]);
			}
			printf("\n");
		}
#endif

#if defined(DEBUG) && DEBUG == 2
		for (i = 1; i < 2 * counter; i++)
			printf("Last: %d %d %d %d %d\n", get_huff[i].weight, 
					get_huff[i].parent,get_huff[i].lchild, 
						get_huff[i].rchild, get_huff[i].ch);
#endif
		break;
	default:
		fprintf(stderr, "Silly boy!\n");
		break;
	}
	return 0;
}
